package cn.xinfei.xdecision.common.service.configcenter.impl;

import cn.xinfei.xdecision.common.dao.configcenter.rejectcode.RejectBranchCodeMapper;
import cn.xinfei.xdecision.common.model.configcenter.rejectcode.model.RejectBranchCodeModel;
import cn.xinfei.xdecision.common.model.configcenter.rejectcode.po.RejectBranchCode;
import cn.xinfei.xdecision.common.model.configcenter.rejectcode.po.RejectCategory;
import cn.xinfei.xdecision.common.model.configcenter.rejectcode.po.RejectCode;
import cn.xinfei.xdecision.common.model.configcenter.rejectcode.po.RejectDiversionLabel;
import cn.xinfei.xdecision.common.model.configcenter.rejectcode.vo.*;
import cn.xinfei.xdecision.common.model.login.SessionManager;
import cn.xinfei.xdecision.common.service.common.sso.SSOService;
import cn.xinfei.xdecision.common.service.common.sso.dto.SSOUserInfoReqDto;
import cn.xinfei.xdecision.common.service.common.sso.dto.SSOUserInfoRespDto;
import cn.xinfei.xdecision.common.service.configcenter.DataCovertUtils;
import cn.xinfei.xdecision.common.service.configcenter.RejectBranchCodeService;
import cn.xinfei.xdecision.common.utils.enums.enginex.RejectBranchCodeAttrEnum;
import cn.xinfei.xdecision.common.utils.exception.ApiException;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.xinfei.xdecision.common.utils.exception.enums.ErrorCodeEnum.*;

@Service
@Slf4j
public class RejectBranchCodeServiceImpl extends ServiceImpl<RejectBranchCodeMapper, RejectBranchCodeModel> implements RejectBranchCodeService {


    @Resource
    private RejectBranchCodeMapper rejectBranchCodeMapper;

    @Autowired
    private SSOService ssoService;

    @Override
    public Void createCategory(RejectCategoryCreateAndUpdateReq rejectCategoryReq) {
        Long organId = SessionManager.getLoginAccount().getOrganId();
        //校验参数
        if (rejectCategoryReq == null || StringUtils.isBlank(rejectCategoryReq.getName())) {
            throw new ApiException(PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage());
        }
        //检测同parent是否有重名
        Long parentId = rejectCategoryReq.getParentId() == null ? 0L : rejectCategoryReq.getParentId();
        List<RejectCategory> rejectCategories = rejectBranchCodeMapper
                .getCategoryByParentId(parentId, organId, rejectCategoryReq.getName());


        if (CollectionUtils.isNotEmpty(rejectCategories)) {
            //重复
            throw new ApiException(
                    REJECT_CATEGORY_NAME_REPEAT.getCode(),
                    REJECT_CATEGORY_NAME_REPEAT.getMessage()
            );
        }
        RejectCategory rejectCategory = new RejectCategory();
        rejectCategory.setName(rejectCategoryReq.getName());
        rejectCategory.setParentId(parentId);
        if (parentId == 0) {
            rejectCategory.setLevel(1);
        } else {
            rejectCategory.setLevel(2);
        }
        rejectCategory.setOrganId(organId);
        rejectBranchCodeMapper.insertRejectCategory(rejectCategory);
        return null;
    }

    @Override
    public RejectCategoryListResp getCategoryList(Long parentId) {
        //校验参数
        if (parentId == null) {
            throw new ApiException(PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage());
        }
        RejectCategoryListResp rejectCategoryListResp = new RejectCategoryListResp();
        List<RejectCategory> rejectCodeList = rejectBranchCodeMapper.getCategoryByParentId(
                parentId,
                SessionManager.getLoginAccount().getOrganId(),
                null);
        if (CollectionUtils.isNotEmpty(rejectCodeList)) {
            List<RejectCategoryResp> list = rejectCodeList.stream().map(DataCovertUtils::covertResp).collect(Collectors.toList());
            rejectCategoryListResp.setList(list);
        } else {
            rejectCategoryListResp.setList(new ArrayList<>());
        }
        return rejectCategoryListResp;
    }

    @Override
    public void createCode(RejectCodeCreateAndUpdateReq rejectCodeReq) {

        Long organId = SessionManager.getLoginAccount().getOrganId();
        //校验参数
        if (rejectCodeReq == null || StringUtils.isBlank(rejectCodeReq.getName()) || rejectCodeReq.getCategoryId() == null) {
            throw new ApiException(PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage());
        }
        //判重
        List<RejectCode> rejectCodeList = rejectBranchCodeMapper.getRejectCodeByCategoryId(null, organId, rejectCodeReq.getName());
        if (CollectionUtils.isNotEmpty(rejectCodeList)) {
            //重复
            throw new ApiException(
                    REJECT_CODE_NAME_REPEAT.getCode(),
                    REJECT_CODE_NAME_REPEAT.getMessage()

            );
        }

        RejectCode rejectCode = new RejectCode();
        rejectCode.setUpdatedTime(rejectCode.getCreatedTime());
        rejectCode.setCategoryId(rejectCodeReq.getCategoryId());
        rejectCode.setName(rejectCodeReq.getName());
        rejectCode.setOrganId(organId);
        rejectBranchCodeMapper.insertRejectCode(rejectCode);


    }

    @Override
    public RejectCodeListResp getBranchCodeList(Long categoryId) {
        //校验参数
        if (categoryId == null) {
            throw new ApiException(PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage());
        }
        RejectCodeListResp rejectCodeListResp = new RejectCodeListResp();
        List<RejectCode> rejectCodeList = rejectBranchCodeMapper.getRejectCodeByCategoryId(categoryId, SessionManager.getLoginAccount().getOrganId(), null);
        if (CollectionUtils.isNotEmpty(rejectCodeList)) {
            List<RejectCodeResp> list = rejectCodeList.stream().map(DataCovertUtils::covertResp).collect(Collectors.toList());
            rejectCodeListResp.setList(list);
        } else {
            rejectCodeListResp.setList(new ArrayList<>());
        }
        return rejectCodeListResp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    public Void createBranchCode(Long userId, RejectBranchCodeCreateAndUpdateReq rejectBranchCodeReq) {
        //监查去重
        checkRejectBranchCodeParam(null, rejectBranchCodeReq);
        RejectBranchCode rejectBranchCode = DataCovertUtils.covertBean(rejectBranchCodeReq);
        //获取拒绝码
        RejectCode rejectCode = rejectBranchCodeMapper.getRejectCodeById(rejectBranchCodeReq.getRejectCodeId());
        if (rejectCode == null) {
            throw new ApiException(REJECT_CODE_NOT_FIND.getCode(), REJECT_CODE_NOT_FIND.getMessage());
        }
        rejectBranchCode.setDisplayName(rejectBranchCodeReq.getAttributes() + rejectCode.getName() + rejectBranchCodeReq.getName());
        rejectBranchCode.setUpdatedTime(rejectBranchCode.getCreatedTime());
        rejectBranchCode.setCreateUserId(userId);
        rejectBranchCode.setOrganId(SessionManager.getLoginAccount().getOrganId());
        try {
            rejectBranchCodeMapper.insertRejectBranchCode(rejectBranchCode);
        } catch (DuplicateKeyException exception) {
            log.error("待插入的拒绝分支码:" + rejectBranchCode.getDisplayName() + "已存在", exception);
            throw new ApiException(
                    REJECT_BRANCH_DISPLAY_NAME_REPEAT.getCode(),
                    REJECT_BRANCH_DISPLAY_NAME_REPEAT.getMessage()
            );
        }
        return null;
    }

    @Override
    public RejectBranchCodeResp getBranchCode(Long id) {
        //校验参数
        if (id == null) {
            throw new ApiException(
                    PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage()
            );
        }

        RejectBranchCode rejectBranch = rejectBranchCodeMapper.getBranchCodeById(id);
        if (rejectBranch == null) {
            return new RejectBranchCodeResp();
        }
        RejectBranchCodeResp rejectBranchCodeResp = DataCovertUtils.covertResp(rejectBranch);
        SSOUserInfoRespDto ssoUserInfoRespDto = ssoService.getUserInfoById(rejectBranchCodeResp.getCreateUserId());
        rejectBranchCodeResp.setCreatedByName(ssoUserInfoRespDto == null ? "" : ssoUserInfoRespDto.getName());
        return rejectBranchCodeResp;
    }


    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    public Void updateBranchCode(Long userId, Long id, RejectBranchCodeCreateAndUpdateReq rejectBranchCodeReq) {
        //校验参数
        checkRejectBranchCodeParam(id, rejectBranchCodeReq);
        //获取拒绝码
        RejectCode rejectCode = rejectBranchCodeMapper.getRejectCodeById(rejectBranchCodeReq.getRejectCodeId());
        if (rejectCode == null) {
            throw new ApiException(
                    REJECT_CODE_NOT_FIND.getCode(),
                    REJECT_CODE_NOT_FIND.getMessage()

            );
        }
        RejectBranchCode rejectBranchCode = DataCovertUtils.covertBean(rejectBranchCodeReq);
        rejectBranchCode.setName(rejectBranchCodeReq.getName());
        rejectBranchCode.setDisplayName(rejectBranchCodeReq.getAttributes() + rejectCode.getName() + rejectBranchCodeReq.getName());
        //只更改备注、导流标签、禁申天数，更新时间
        try {
            rejectBranchCodeMapper.updateRejectBranchCode(id, rejectBranchCode);
        } catch (DuplicateKeyException exception) {
            log.error("待插入的拒绝分支码:" + rejectBranchCode.getDisplayName() + "已存在", exception);
            throw new ApiException(
                    REJECT_BRANCH_DISPLAY_NAME_REPEAT.getCode(),
                    REJECT_BRANCH_DISPLAY_NAME_REPEAT.getMessage()

            );
        }
        return null;
    }

    private void checkRejectBranchCodeParam(Long id, RejectBranchCodeCreateAndUpdateReq rejectBranchCodeReq) {
        //校验参数
        if (rejectBranchCodeReq == null || StringUtils.isBlank(rejectBranchCodeReq.getName()) || rejectBranchCodeReq.getRejectCodeId() == null || rejectBranchCodeReq.getAttributes() == null) {
            throw new ApiException(
                    PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage()

            );
        }
        if (!isNumber(rejectBranchCodeReq.getName())) {
            throw new ApiException(
                    REJECT_BRANCH_NAME_PARAM_ERROR.getCode(),
                    REJECT_BRANCH_NAME_PARAM_ERROR.getMessage()

            );
        }
        RejectBranchCodeAttrEnum rejectBranchCodeAttrEnum = RejectBranchCodeAttrEnum.getRejectBranchCodeAttr(rejectBranchCodeReq.getAttributes());
        //校验参数
        if (rejectBranchCodeAttrEnum == null) {
            throw new ApiException(
                    REJECT_BRANCH_CODE_ATTR_PARAM_ERROR.getCode(),
                    REJECT_BRANCH_CODE_ATTR_PARAM_ERROR.getMessage()

            );
        }
        List<RejectBranchCode> rejectBranchCodeList = rejectBranchCodeMapper.getRejectBranchCode(rejectBranchCodeReq.getRejectCodeId(), rejectBranchCodeReq.getName());
        if (CollectionUtils.isNotEmpty(rejectBranchCodeList)) {
            //创建
            if (id == null) {
                //重复
                throw new ApiException(
                        REJECT_BRANCH_NAME_REPEAT.getCode(),
                        REJECT_BRANCH_NAME_REPEAT.getMessage()

                );
            } else {
                //更新
                if (rejectBranchCodeList.size() >= 2) {
                    //重复
                    throw new ApiException(
                            REJECT_BRANCH_NAME_REPEAT.getCode(),
                            REJECT_BRANCH_NAME_REPEAT.getMessage()

                    );
                } else if (!rejectBranchCodeList.get(0).getId().equals(id)) {
                    //重复
                    throw new ApiException(
                            REJECT_BRANCH_NAME_REPEAT.getCode(),
                            REJECT_BRANCH_NAME_REPEAT.getMessage()

                    );
                }

            }
        }
    }

    @Override
    public void removeBranchCode(Long id) {
        //校验参数
        if (id == null) {
            throw new ApiException(
                    PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage()

            );
        }
        rejectBranchCodeMapper.removeRejectBranchCode(id);
    }

    @Override
    public PageInfo<RejectBranchCodeResp> searchBranchCode(RejectBranchCodeSearchReq rejectBranchCodeSearchReq) {
        List<Long> orgIdList = SessionManager.getLoginAccount().getOrgIdList();
        rejectBranchCodeSearchReq.setOrgIdList(orgIdList);
        PageMethod.startPage(rejectBranchCodeSearchReq.getPageNum(), rejectBranchCodeSearchReq.getPageSize());
        List<RejectBranchCode> rejectBranchCodes = rejectBranchCodeMapper.searchBranchCode(rejectBranchCodeSearchReq);
        PageInfo<RejectBranchCode> pageInfo = new PageInfo<>(rejectBranchCodes);

        PageInfo<RejectBranchCodeResp> pageInfo1 = new PageInfo<>();
        if (CollectionUtils.isNotEmpty(pageInfo.getList())) {
            List<Long> userIds = pageInfo.getList().stream().map(RejectBranchCode::getCreateUserId).collect(Collectors.toList());

            SSOUserInfoReqDto ssoUserInfoReqDto = new SSOUserInfoReqDto();
            ssoUserInfoReqDto.setId(userIds);
            List<SSOUserInfoRespDto> userInfoRespDtos = ssoService.getUserInfos(ssoUserInfoReqDto);

            Map<Long, String> userMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(userInfoRespDtos)) {
                userMap = userInfoRespDtos.stream().collect(Collectors.toMap(SSOUserInfoRespDto::getId, SSOUserInfoRespDto::getName, (a, b) -> a));
            }
            Map<Long, String> finalUserMap = userMap;
            List<RejectBranchCodeResp> list = pageInfo.getList().stream().map(DataCovertUtils::covertResp)
                    .peek(r -> r.setCreatedByName(finalUserMap.get(r.getCreateUserId()))
                    ).collect(Collectors.toList());


            pageInfo1.setList(list);
            pageInfo1.setTotal(pageInfo.getTotal());
        }
        return pageInfo1;
    }

    @Override
    public void createDiversionLabel(RejectDiversionLabelCreateAndUpdateReq rejectDiversionLabelReq) {
        //校验参数
        Long organId = SessionManager.getLoginAccount().getOrganId();
        checkDiversionLabelParam(null, rejectDiversionLabelReq, organId);
        RejectDiversionLabel rejectDiversionLabel = new RejectDiversionLabel();
        rejectDiversionLabel.setWeights(rejectDiversionLabelReq.getWeights());
        rejectDiversionLabel.setName(rejectDiversionLabelReq.getName());
        rejectDiversionLabel.setOrganId(organId);
//        rejectDiversionLabel.setRemark(rejectDiversionLabelReq.getRemark());
        rejectBranchCodeMapper.insertRejectDiversionLabel(rejectDiversionLabel);
    }

    @Override
    public void updateDiversionLabel(Long id, RejectDiversionLabelCreateAndUpdateReq rejectDiversionLabelReq) {
        //校验参数
        Long organId = SessionManager.getLoginAccount().getOrganId();
        checkDiversionLabelParam(id, rejectDiversionLabelReq, organId);
        RejectDiversionLabel rejectDiversionLabel = new RejectDiversionLabel();
        rejectDiversionLabel.setWeights(rejectDiversionLabelReq.getWeights());
        rejectDiversionLabel.setName(rejectDiversionLabelReq.getName());
        rejectDiversionLabel.setRemark(rejectDiversionLabelReq.getRemark());
        rejectBranchCodeMapper.updateRejectDiversionLabel(id, rejectDiversionLabel);

    }

    private void checkDiversionLabelParam(Long id, RejectDiversionLabelCreateAndUpdateReq rejectDiversionLabelReq, Long organId) {
        if (rejectDiversionLabelReq == null || StringUtils.isBlank(rejectDiversionLabelReq.getName()) || rejectDiversionLabelReq.getWeights() == null) {
            throw new ApiException(
                    PARAMS_EXCEPTION.getCode(), PARAMS_EXCEPTION.getMessage()

            );
        }
        if (!isLetterDigit(rejectDiversionLabelReq.getName())) {
            throw new ApiException(
                    REJECT_DIVERSION_NAME_PARAM_ERROR.getCode(),
                    REJECT_DIVERSION_NAME_PARAM_ERROR.getMessage()

            );
        }
        if (rejectDiversionLabelReq.getWeights() > 99 || rejectDiversionLabelReq.getWeights() < 1) {
            throw new ApiException(
                    REJECT_DIVERSION_WEIGHTS_PARAM_ERROR.getCode(),
                    REJECT_DIVERSION_WEIGHTS_PARAM_ERROR.getMessage()

            );
        }
        List<RejectDiversionLabel> rejectDiversionLabelByName = rejectBranchCodeMapper.getRejectDiversionLabelByName(rejectDiversionLabelReq.getName(), organId);
        if (CollectionUtils.isNotEmpty(rejectDiversionLabelByName)) {
            if (id == null) {
                throw new ApiException(
                        REJECT_DIVERSION_NAME_REPEAT.getCode(),
                        REJECT_DIVERSION_NAME_REPEAT.getMessage()

                );
            } else {
                if (rejectDiversionLabelByName.size() >= 2) {
                    throw new ApiException(
                            REJECT_DIVERSION_NAME_REPEAT.getCode(),
                            REJECT_DIVERSION_NAME_REPEAT.getMessage()

                    );
                } else {
                    if (!rejectDiversionLabelByName.get(0).getId().equals(id)) {
                        throw new ApiException(
                                REJECT_DIVERSION_NAME_REPEAT.getCode(),
                                REJECT_DIVERSION_NAME_REPEAT.getMessage()
                        );
                    }
                }

            }
        }

    }

    @Override
    public PageInfo<RejectDiversionLabelResp> getDiversionLabel(Integer pageNum, Integer pageSize) {
        PageMethod.startPage(pageNum, pageSize);
        List<RejectDiversionLabel> rejectDiversionLabels = rejectBranchCodeMapper.getRejectDiversionLabelAll(SessionManager.getLoginAccount().getOrgIdList());
        PageInfo<RejectDiversionLabel> pageInfo = new PageInfo<>(rejectDiversionLabels);

        PageInfo<RejectDiversionLabelResp> pageInfo1 = new PageInfo<>();
        if (CollectionUtils.isNotEmpty(pageInfo.getList())) {
            List<RejectDiversionLabelResp> list = pageInfo.getList().stream().map(DataCovertUtils::covertResp).collect(Collectors.toList());


            pageInfo1.setList(list);
            pageInfo1.setTotal(pageInfo.getTotal());
            return pageInfo1;
        }
        return pageInfo1;
    }

    @Override
    public RejectDiversionLabelListResp getRejectDiversionLabelAll() {
        RejectDiversionLabelListResp rejectDiversionLabelListResp = new RejectDiversionLabelListResp();
        List<RejectDiversionLabel> rejectDiversionLabels = rejectBranchCodeMapper.getRejectDiversionLabelAll(SessionManager.getLoginAccount().getOrgIdList());
        if (CollectionUtils.isNotEmpty(rejectDiversionLabels)) {
            List<RejectDiversionLabelResp> list = rejectDiversionLabels.stream().map(DataCovertUtils::covertResp).collect(Collectors.toList());
            rejectDiversionLabelListResp.setList(list);
        } else {
            rejectDiversionLabelListResp.setList(new ArrayList<>());
        }
        return rejectDiversionLabelListResp;
    }


    public static boolean isLetterDigit(String str) {
        String regex = "^[a-z0-9A-Z]+$";
        return str.matches(regex);
    }

    public static boolean isNumber(String str) {
        String regex = "^[0-9]+$";
        return str.matches(regex);
    }


}
